package org.rayson.server;

import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;

import org.rayson.server.transport.ServerConnection;
import org.rayson.server.transport.ServerSelector;
import org.rayson.share.logger.RasonLoggerFactory;
import org.rayson.share.transport.NioChannel;
import org.slf4j.Logger;

public class ConnectionManager implements Manager, Runnable {
	private static Logger LOGGER = RasonLoggerFactory
			.getLogger(ServerSelector.class);
	private final AtomicLong connectionId;
	private final Container container;
	private final ConcurrentHashMap<Long, ServerConnection> connections;
	private final LinkedBlockingQueue<ServerConnection> recycleConnections;
	private boolean running;

	private Thread thread;

	ConnectionManager(final Container container) {
		this.container = container;
		connectionId = new AtomicLong();
		connections = new ConcurrentHashMap<>();
		recycleConnections = new LinkedBlockingQueue<ServerConnection>();
	}

	/**
	 * @param connection
	 */
	public void add(final ServerConnection connection) {
		connections.put(connection.getId(), connection);
	}

	/**
	 * @param recycleC
	 */
	private void doRecycle(final ServerConnection recycleC) {
		
	}

	@Override
	public Container getContainer() {
		return this.container;
	}

	@Override
	public String getName() {
		return "Connection Manager of " + container.getName();
	}

	/**
	 * @param nioChannel
	 * @return
	 */
	public ServerConnection newConnection(final NioChannel nioChannel) {
		return new ServerConnection(container, nioChannel,
				connectionId.getAndIncrement());
	}

	/**
	 * Recycle an connection.
	 * 
	 * @param connection
	 */
	public void recycle(final ServerConnection connection) {
		recycleConnections.add(connection);
	}

	@Override
	public void run() {
		while (running) {
			try {
				final ServerConnection recycleC = recycleConnections.take();
				LOGGER.info("recycle connection" + recycleC);
				doRecycle(recycleC);
			} catch (final InterruptedException e) {
				continue;
			}
		}
	}

	@Override
	public void start(final Properties properties) {
		running = true;
		thread = new Thread(this, getName());
		thread.start();
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub

	}

}